package studia.figlewicz.math.library;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

public class ZarzadcaWyceny {
	
	private LinkedHashMap<Date, Double> krzywaDyskonta = null;
	private Date dataWyceny = null;
	public void setDyskonto(KrzywaStopyProcentowej krzywaDyskonta, Date dataWyceny) {
		this.krzywaDyskonta = krzywaDyskonta.getPunkty();
		this.dataWyceny = dataWyceny;
	}
	
	private Set<PrzeplywPieniezny> przeplywy = new HashSet<PrzeplywPieniezny>();
	public Set<PrzeplywPieniezny> getPrzeplywy() {
		return przeplywy;
	}
	public void setPrzeplywy(Set<PrzeplywPieniezny> przeplywy) {
		this.przeplywy = przeplywy;
	}
	public void dodajPrzeplyw(PrzeplywPieniezny przeplyw) {
		przeplywy.add(przeplyw);
	}

	private Set<ZmiennaRynkowa> zmienneRynkowe  = new HashSet<ZmiennaRynkowa>();
	public Set<ZmiennaRynkowa> getZmienneRynkowe() {
		return zmienneRynkowe;
	}
	public void setZmienneRynkowe(Set<ZmiennaRynkowa> zmienneRynkowe) {
		this.zmienneRynkowe = zmienneRynkowe;
	}
	public void dodajZmiennaRynkowa(Model model, String zmiennaObjasniana) {
		zmienneRynkowe.add(new ZmiennaRynkowa(model, zmiennaObjasniana));
	}
	public void dodajZmiennaRynkowa(ZmiennaRynkowa zmiennaRynkowa) {
		zmienneRynkowe.add(zmiennaRynkowa);
	}
	public void usunZmiennaRynkowa(Model model, String zmiennaObjasniana) {
		ZmiennaRynkowa resoult = null;
		for (ZmiennaRynkowa ip : zmienneRynkowe) {
			if (ip.getModel() == model && ip.getZmiennaObjasniana().equals(zmiennaObjasniana)) {
				resoult = ip;
				break;
			}
		}
		zmienneRynkowe.remove(resoult);
	}
	public void usunZmienneRynkowe(Model model) {
		for (ZmiennaRynkowa ip : zmienneRynkowe) {
			if (ip.getModel() == model)
				zmienneRynkowe.remove(ip);
		}
	}
	public void usunZmiennaRynkowa(ZmiennaRynkowa zmiennaRynkowa) {
		zmienneRynkowe.remove(zmiennaRynkowa);
	}
	public ZmiennaRynkowa getZmiennaRynkowa(Model model, String zmiennaObjasniana) {
		ZmiennaRynkowa resoult = null;
		for (ZmiennaRynkowa ip : zmienneRynkowe) {
			if (ip.getModel() == model && ip.getZmiennaObjasniana().equals(zmiennaObjasniana)) {
				resoult = ip;
				break;
			}
		}
		return resoult;
	}
	
	
	private Map<PrzeplywPieniezny, WynikWyceny> wynikiWyceny  = new HashMap<PrzeplywPieniezny, WynikWyceny>();
	private StatystykaWyceny wykonajWycene(PrzeplywPieniezny przeplyw, MagazynMonteCarlo magazyn, int numerSymulacji) {
		StatystykaWyceny resoult = new StatystykaWyceny();
		
		Map<String, TrajektoriaProcesu> trajektorieDoWyceny = new HashMap<String, TrajektoriaProcesu>();
		
		for (String s : przeplyw.getInstrumentyPodstawowe()) {
			ZmiennaRynkowa zr = przeplyw.getZmiennaRynkowa(s);
			TrajektoriaProcesu tp = magazyn.getTrajektorieSymulacji(zr.getModel(), zr.getZmiennaObjasniana(), numerSymulacji);
			trajektorieDoWyceny.put(s, tp);
		}
		
		przeplyw.setDyskonto(krzywaDyskonta, dataWyceny);
		
		resoult = przeplyw.obliczWyplate(trajektorieDoWyceny);
		
		return resoult;
	}
	
	public void wycenaMonteCarlo(PrzeplywPieniezny przeplyw, MagazynMonteCarlo magazyn, int liczbaSymulacji) {
		WynikWyceny resoult = new WynikWyceny(przeplyw);
		resoult.setWartoscNominalna(new Double(0));
		resoult.setWartoscRealna(new Double(0));
		
		for (int i=0; i<liczbaSymulacji; i++) {
			StatystykaWyceny temp = wykonajWycene(przeplyw, magazyn, i);
			if (temp.wartoscNominalna != null) {
				resoult.setWartoscNominalna(resoult.getWartoscNominalna() + temp.wartoscNominalna);
			}
			if (temp.wartoscRealna != null) {
				resoult.setWartoscRealna(resoult.getWartoscRealna() + temp.wartoscRealna);
			}
			resoult.addStatystykaWyceny(temp);
		}
		
		resoult.setWartoscNominalna(resoult.getWartoscNominalna() / liczbaSymulacji);
		resoult.setWartoscRealna(resoult.getWartoscRealna() / liczbaSymulacji);
		
		przeplyw.setWynikWyceny(resoult);
	}

	
}
 
